#include "fileList.srpc.h"

#include <workflow/MySQLResult.h>
#include <wfrest/HttpServer.h>
#include <workflow/WFFacilities.h>
#include <map>
#include <iostream>
#include <signal.h>
#include <string>
using std::string;
using std::map;

using namespace srpc;
using namespace wfrest;
using namespace srpc;
using namespace protocol;

static WFFacilities::WaitGroup wait_group(1);

void sig_handler(int signo)
{
	wait_group.done();
}

struct FileListContext{
	FileListResponse *resp;
};

class FileListServiceImpl : public FileList::Service
{
public:

	void fileList(FileListRequest *request, FileListResponse *response, srpc::RPCContext *ctx) override
	{
		SeriesWork * series = ctx->get_series();
		string username = request->username();
		 string sql = "select file_table.hashcode,                \
                                 file_table.size,                    \
                                 subquery.filename,                  \
                                 subquery.created_at,                \
                                 subquery.last_update                \
                          from file_table                            \
                          RIGHT JOIN                                  \
                          (                                          \
                            select fid,filename,created_at,last_update   \
                            from user_file_table                     \
                            where username = '"+username+"'          \
                          ) AS subquery                              \
                          ON file_table.id = subquery.fid;";

            WFMySQLTask * mysqltask = WFTaskFactory::create_mysql_task("mysql://root:123@localhost/newCloudDisk",3,&FileListServiceImpl::filelistMysqlCallback);
            mysqltask->get_req()->set_query(sql);
            FileListContext * context = new FileListContext{response};
			series->set_context(context);
        	series->set_callback([context](const SeriesWork *){
                delete context;
        	});
        	series->push_back(mysqltask);
	}
private:
	static void filelistMysqlCallback(WFMySQLTask * mysqlTask){
FileListContext * context = static_cast<FileListContext*>(series_of(mysqlTask)->get_context());
    if(mysqlTask->get_state() !=WFT_STATE_SUCCESS){
        context->resp->set_success(0);
        return;
    }

    MySQLResultCursor cursor(mysqlTask->get_resp());

    if(cursor.get_cursor_status()==MYSQL_PACKET_ERROR){
        context->resp->set_success(0);
        return ;
    }

    if(cursor.get_cursor_status()==MYSQL_STATUS_GET_RESULT){
		context->resp->set_success(1);
		map<string,MySQLCell> row;
        cursor.fetch_row(row);
		do{
            if(row.size()==0){
				context->resp->set_has(0);
                return;
            }
            context->resp->add_filehash(row["hashcode"].as_string());
            context->resp->add_filename(row["filename"].as_string());
			context->resp->add_filesize(std::to_string(row["size"].as_int()));
			context->resp->add_lastupdated(row["created_at"].as_datetime());
			context->resp->add_uploadat(row["last_update"].as_datetime());

        }while(cursor.fetch_row(row));
		context->resp->set_has(1);
	}
	return ;
	}
};

int main()
{
    signal(SIGINT,sig_handler); 
    GOOGLE_PROTOBUF_VERIFY_VERSION;
    unsigned short port = 1414;
    SRPCServer server;

    FileListServiceImpl usrInfo_impl;
    server.add_service(&usrInfo_impl);

    if(server.start(port) == 0){
        wait_group.wait();
        server.stop();
        google::protobuf::ShutdownProtobufLibrary();
    }else{
        std::cerr << "Error: start signserver failed!\n";
        std::exit(1);
    }

    return 0;
}
